import React, { Component } from 'react';
import { View, Keyboard, ScrollView, Platform } from 'react-native';
import { observer } from 'mobx-react';
import t from 'tcomb-form-native';
import _ from 'lodash';
import store from './model';
import styles from './styles';
import TextBox from './textBox';
import Title from './title';
import stylesheet from './bootstrap';

let timer;
const BOTTOM_HEIGHT = 30

class FormComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      values: props.initialValue || {},
      submiting: false,
      kbHeight: BOTTOM_HEIGHT,
    };
  }
  setkbHeight = (e, hide) => {
    Platform.select({
      ios: () => {
        this.setState({
          kbHeight: hide ? BOTTOM_HEIGHT : (e.startCoordinates.height) * 1.3
        })
      },
      android: v => v
    })();
  }
  componentWillMount() {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.setkbHeight.bind(this));
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.setkbHeight.bind(this, true));
  }
  componentDidMount() {
    if (_.isFunction(this.props.onChange)) {
      this.props.onChange(this.state.values);
    }
  }
  componentWillReceiveProps(next) {
    if (!_.isEqual(next.initialValue, this.props.initialValue)) {
      this.setState({
        values: next.initialValue
      });
    }
    if (next.reset) {
      this.setState(
        {
          values: this.props.initialValue
        },
        () => {
          this.props._store.unReset.call(this.props._store);
        }
      );
    }
    if (next.status !== this.props.submitStatus) {
      if (next.status && !this.state.submiting) {
        this.setState(
          {
            submiting: true
          },
          () => {
            this.submitHandle();
          }
        );
      } else if (!next.status) {
        this.setState({
          submiting: false
        });
      }
    }
  }
  componentWillUnmount() {
    timer && clearTimeout(timer);
    this.props._store.resetModel.call(this.props._store);
  }
  changeHandler = values => {
    this.setState(
      {
        values
      },
      () => {
        if (_.isFunction(this.props.onChange)) {
          this.props.onChange(values);
        }
        this.props._store.setValue.call(this.props._store, values);
      }
    );
  };
  getValues = () => {
    const value = this.refs.form.getValue();
    if (value) {
      const res = {};
      _.forEach(value, (v, k) => {
        if (!_.includes(this.props.filterValues, k)) {
          res[k] = v;
        }
      });
      this.props.onSubmit.call(this.props._store, {
        ...res,
        ...this.props.extraValue,
      });
    }
    this.props._store.unSubmit.call(this.props._store);
  }
  submitHandle = () => {
    Platform.select({
      ios: () => {
        Keyboard.dismiss();
        timer = setTimeout(this.getValues, 300)
      },
      android: this.getValues
    })();
  };
  extraForTextBox = (options) => {
    if (!options.fields) {
      return options;
    }
    _.forEach(options.fields, (option, key) => {
      if (option.factory && option.factory.name === 'MyTextBox') {
        option.onChange = this.onChangeNative
      }
    })
    return options;
  }
  render() {
    return (
      <View style={styles.wrap}>
        <ScrollView style={styles.wrap}>
          <t.form.Form
            ref="form"
            type={t.struct(this.props.formType)}
            options={this.extraForTextBox(this.props.options)}
            value={this.state.values}
            onChange={this.changeHandler}
            stylesheet={stylesheet}
          />
          {this.props.extra}
          <View style={{ height: this.state.kbHeight }} />
        </ScrollView>
      </View>
    );
  }
}
const Form = observer(props => {
  return (
    <FormComp
      _store={store}
      reset={store.resetStatus}
      status={store.submitStatus}
      {...props}
    />
  );
});

Form.submit = () => store.submit();
Form.reset = () => store.reset();
Form.getValue = () => store.getValue();
Form.stylesheet = stylesheet;
Form.t = t;
Form.TextBox = TextBox;
Form.Title = Title;
export default Form;
